package org.jground.rx.ui.zk;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jground.rx.IRXObject;
import org.jground.rx.IRXObjectSynopsis;
import org.jground.rx.IRXObjectUtils;
import org.jground.rx.RXAccess;
import org.jground.rx.RXObjectService;
import org.jground.util.CollectionUtils;
import org.jground.util.StringUtils;
import org.jground.zk.zulX.HboxX;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.AbstractListModel;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Image;
import org.zkoss.zul.ListModelExt;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listhead;
import org.zkoss.zul.Listheader;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.event.ListDataEvent;

public class UIResultList extends Listbox implements EventListener {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static Log logger = LogFactory.getLog(UIResultList.class);

    public static int MAXCHARS = 64;
    public static int DATA_COLS = 3;

    public static Hbox uiBox(UIResultList resultList) {
        HboxX hbox = new HboxX(resultList);
        hbox.setWidth("550px");
        hbox.setStyle("padding: 4px");
        return hbox;
    }
    //
    //
    //
    private List<IRXObjectSynopsis> list = new ArrayList<IRXObjectSynopsis>();
    private _UIResultListModel model;
    private UIFrame uiFrame;
    private ListitemRenderer postfixRenderer;
    private ListitemRenderer prefixRenderer;
    private EventListener externalEventListener;

    public UIResultList(UIFrame uiFrame) {
        this.uiFrame = uiFrame;
        int maxWidth = UIStyles.getInstance().getMaxWidth() - 64;
        // addEventListener(Events.ON_SELECT, this);

        Listhead head = new Listhead();
        head.setSizable(true);
        head.setParent(this);
        // icon
        Listheader lhr = new Listheader();
        lhr.setWidth("32px");
        lhr.setSort("auto");
        lhr.setParent(head);
        //
        String percentage = (maxWidth / DATA_COLS) + "px";
        //
        for (int index = 0; index < DATA_COLS; index++) {
            lhr = new Listheader("");
            lhr.setWidth(percentage);
            lhr.setParent(head);
        }
        // possible checkbox/radiobutton of postfix renderer
         lhr = new Listheader();
        lhr.setWidth("32px");
        lhr.setSort("auto");
        lhr.setParent(head);

        //
        //
        //
        
        model = new _UIResultListModel();
        this.setModel(model);
        this.setItemRenderer(new _UIResultListRenderer2());
        this.setMold("paging");
        this.setPageSize(10);
    }
    
    
    
    
    
    
    
    

    public UIResultList(UIFrame uiFrame, List<IRXObjectSynopsis> list) {
        this(uiFrame);
        setObjects(list);
    }

    private void setObjects(List<IRXObjectSynopsis> list) {
        this.list = list;
        model.update();
        logger.debug("setObjects");
    }

    public void onEvent(Event event) throws Exception {
        if (event.getTarget() instanceof Listcell) {
            Listcell t = (Listcell) event.getTarget();
            try {
                Long oid = (Long) t.getAttribute("oid");
                IRXObject obj = RXObjectService.getInstance().getById(oid);
                if (RXAccess.getInstance().canRead(obj)) {
                    uiFrame.openView(oid, true);
                }
            } catch (Exception e) {
                logger.error(e, e);
            }

        }
    }

    public void detach() {
        model = null;
        uiFrame = null;
        if (list != null) {
            list.clear();
            list = null;
        }
        super.detach();
    }

    public ListitemRenderer getPostfixRenderer() {
        return postfixRenderer;
    }

    public void setPostfixRenderer(ListitemRenderer postfixRenderer) {
        this.postfixRenderer = postfixRenderer;
    }

    public void setExternalEventListener(EventListener externalEventListener) {
        this.externalEventListener = externalEventListener;
    }

    public ListitemRenderer getPrefixRenderer() {
        return prefixRenderer;
    }

    public void setPrefixRenderer(ListitemRenderer prefixRenderer) {
        this.prefixRenderer = prefixRenderer;
    }

    public void removeAllObject() {
        model.removeAll();
    }

    public void addObjects(IRXObjectSynopsis... dataObjects) {
        model.addAll(dataObjects);
    }

    public void addObjects(List<? extends IRXObjectSynopsis> mods) {
        addObjects(mods.toArray(IRXObjectUtils.EMPTY_RXDataObject_ARRAY));
    }

    public Collection<IRXObjectSynopsis> getObjects() {
        return new ArrayList<IRXObjectSynopsis>(list);
    }

    public void removeObject(IRXObjectSynopsis mod) {
        model.removeObject(mod);
    }

    public int objectCount() {
        return model.objectCount();
    }

    private class _UIResultListModel extends AbstractListModel implements ListModelExt {

        /**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public Object getElementAt(int index) {
            return list.get(index);
        }

        public int getSize() {
            return list.size();
        }

        public void update() {
            fireEvent(ListDataEvent.CONTENTS_CHANGED, 0, list.size());
        }

        public void removeAll() {
            int size = list.size();
            fireEvent(ListDataEvent.CONTENTS_CHANGED, 0, list.size());
            list.clear();
            fireEvent(ListDataEvent.CONTENTS_CHANGED, 0, size);
        }

        public void addAll(IRXObjectSynopsis[] mods) {
            // fireEvent(ListDataEvent.CONTENTS_CHANGED, 0, list.size());
            for (IRXObjectSynopsis mod : mods) {
                CollectionUtils.addUnique(list, mod);
            }
            fireEvent(ListDataEvent.CONTENTS_CHANGED, 0, list.size());
        }

        public void removeObject(IRXObjectSynopsis mod) {
            if (mod == null) {
                return;
            }
            int size = list.size();
            int index = list.indexOf(mod);
            if (index != -1) {
                list.remove(index);
            }
            fireEvent(ListDataEvent.CONTENTS_CHANGED, 0, size);
        }

        public int objectCount() {
            return list.size();
        }

        @SuppressWarnings("rawtypes")
        public void sort(Comparator cmpr, boolean ascending) {
            // TODO Auto-generated method stub
        }

    }


    public class _UIResultListRenderer2 implements ListitemRenderer {

        public void render(Listitem item, Object data) throws Exception {
            if (prefixRenderer != null) {
                prefixRenderer.render(item, data);
            }
            Listcell cell = null;
            if (data instanceof IRXObjectSynopsis) {
                IRXObjectSynopsis rxd = (IRXObjectSynopsis) data;
                // ICON
                cell = new Listcell();
                cell.setStyle("padding: 8px 6px 8px 6px");

                Image image = new Image();
                image.setContent(UIStyles.getInstance().getImage(rxd, UIStyles.S));
                image.setParent(cell);
                cell.setParent(item);

                addEventListener(rxd, cell);
                cell.setAttribute("oid", rxd.getOid());
                //
                List<String> synopsis = uiFrame.getUISynopsisRendererFactory().render(rxd, "");
                // String[] synopsis = rxd.toSynopsis();
                String s = null;
                for (int index = 0; index < DATA_COLS; index++) {
                    if (index < synopsis.size()) {
                        s = StringUtils.cutToMax(synopsis.get(index), MAXCHARS);
                    } else {
                        s = " ";
                    }
                    cell = new Listcell(s);
                    cell.setParent(item);
                    addEventListener(rxd, cell);
                    cell.setAttribute("oid", rxd.getOid());
                    // cell.setWidth(percent);
                }
            }
            if (postfixRenderer != null) {
                postfixRenderer.render(item, data);
            }
        }

        private void addEventListener(IRXObjectSynopsis mod, Listcell cell) {
            if (externalEventListener != null) {
                cell.addEventListener(Events.ON_CLICK, externalEventListener);
            } else if (mod.getRXClass().isTopLevel()) {
                cell.addEventListener(Events.ON_CLICK, UIResultList.this);
            }
        }
    }

}
